#include "CMan.h"
#include "LessonX.h"
#include <cmath>
#include <cstring>

#include <Windows.h>
#include <mmsystem.h>
#pragma comment(lib, "Winmm.lib")

CMan::CMan(const char* szName) : CWeapon(szName)
{
    m_bIsJumping = false;
    m_bIsRunning = false;
    m_fMoveSpeed = 20.0f;     // 左右移动速度
    m_fJumpSpeed = 15.0f;     // 跳跃初速度
    m_fCurrentSpeedX = 0.0f;
    m_fCurrentSpeedY = 0.0f;
    m_fGravity = 20.0f;      // 重力加速度
    m_bLeftPressed = false;
    m_bRightPressed = false;
    m_bCanJump = true;      // 初始允许跳跃
}

CMan::~CMan()
{

}

void CMan::Init()
{
    // 基本碰撞设置
    SetSpriteCollisionActive(true, true);
    SetSpriteCollisionResponse(COL_RESPONSE_CUSTOM);
    SetSpriteWorldLimitMode(WORLD_LIMIT_NULL);
}

void CMan::OnMove(float fDeltaTime)
{
    if (m_bLeftPressed) {
        m_fCurrentSpeedX = -m_fMoveSpeed;
        SetSpriteFlipX(true);
        m_bIsRunning = true;
    }
    else if (m_bRightPressed) {
        m_fCurrentSpeedX = m_fMoveSpeed;
        SetSpriteFlipX(false);
        m_bIsRunning = true;
    }
    else {
        m_fCurrentSpeedX = 0;
        m_bIsRunning = false;
    }

    // 应用重力
    m_fCurrentSpeedY += m_fGravity * fDeltaTime;
    if (m_fCurrentSpeedY > 220.0f) {
        m_fCurrentSpeedY = 220.0f; // 限制下落速度
    }

    // 更新位置
    float newX = GetSpritePositionX() + m_fCurrentSpeedX * fDeltaTime;
    float newY = GetSpritePositionY() + m_fCurrentSpeedY * fDeltaTime;
    SetSpritePosition(newX, newY);
}

void CMan::OnKeyDown(int iKey)
{
    switch (iKey)
    {
        case KEY_LEFT:
            m_bLeftPressed = true;
            m_fCurrentSpeedX = -m_fMoveSpeed;
            break;
        case KEY_RIGHT:
            m_bRightPressed = true;
            m_fCurrentSpeedX = m_fMoveSpeed;
            break;
        case KEY_SPACE:
            if (m_bCanJump) {
                PlaySound("game/data/audio/jump2.wav", 0, 1);
                m_fCurrentSpeedY = -m_fJumpSpeed;
                m_bIsJumping = true;
                //m_bCanJump = false;
            }
            break;
    }
}

void CMan::OnKeyUp(int iKey)
{
    switch (iKey)
    {
        case KEY_LEFT:
            m_bLeftPressed = false;
            if (!m_bRightPressed) m_fCurrentSpeedX = 0;
            break;
        case KEY_RIGHT:
            m_bRightPressed = false;
            if (!m_bLeftPressed) m_fCurrentSpeedX = 0;
            break;
    }
}

void CMan::OnSpriteColSprite(CWeapon* pSprite)
{
    const char* spriteName = pSprite->GetName();

    // 处理与trap的碰撞
    if (strstr(spriteName, "trap") != nullptr)
    {

        // 隐藏自己
        SetSpriteVisible(false);
        SetSpriteCollisionActive(false, false);

        // 设置游戏状态为3（失败）
        g_GameMain.SetGameState(3);
        return;
    }

    // 处理与door的碰撞
    if (strstr(spriteName, "door") != 0)
    {
        // 隐藏门精灵本身
        pSprite->SetSpriteVisible(false);
        pSprite->SetSpriteCollisionActive(false, false);

        // 设置游戏状态为0（胜利或结束）
        g_GameMain.SetGameState(0);
    }
    // 处理与所有di平台的碰撞
    else if (strstr(spriteName, "di") != 0)
    {
        HandleDiCollision(pSprite);
    }
}

void CMan::Jump()
{
    // 只有在与平台碰撞后允许跳跃
    if (m_bCanJump) {
        m_fCurrentSpeedY = -m_fJumpSpeed;
        m_bIsJumping = true;
        m_bCanJump = false;  // 消耗跳跃权限
    }
}

void CMan::MoveLeft()
{
    m_bLeftPressed = true;
    m_bRightPressed = false;
    SetCurrentSpeedX(-m_fMoveSpeed);
    SetSpriteFlipX(true);
    m_bIsRunning = true;
}

void CMan::MoveRight()
{
    m_bRightPressed = true;
    m_bLeftPressed = false;
    SetCurrentSpeedX(m_fMoveSpeed);
    SetSpriteFlipX(false);
    m_bIsRunning = true;
}

void CMan::Stop()
{
    m_bLeftPressed = false;
    m_bRightPressed = false;
    SetCurrentSpeedX(0);
    m_bIsRunning = false;
}

void CMan::OnSpriteColWorldLimit(int iColSide)
{
    float screenLeft = CSystem::GetScreenLeft();
    float screenRight = CSystem::GetScreenRight();
    float screenTop = CSystem::GetScreenTop();
    float screenBottom = CSystem::GetScreenBottom();

    switch(iColSide)
    {
        case 0: // 左边界
            SetSpritePositionX(screenLeft + GetSpriteWidth()/2 + 1.0f);
            SetCurrentSpeedX(0);
            break;

        case 1: // 右边界
            SetSpritePositionX(screenRight - GetSpriteWidth()/2 - 1.0f);
            SetCurrentSpeedX(0);
            break;

        case 2: // 上边界
            SetSpritePositionY(screenTop - GetSpriteHeight()/2 - 1.0f);
            SetCurrentSpeedY(0);
            break;

        case 3: // 下边界
            PlaySound("game/data/audio/die.wav", 0, 1);
            SetSpritePositionY(screenBottom + GetSpriteHeight()/2 + 1.0f);
            SetCurrentSpeedY(0);
            SetSpriteVisible(false);
            SetSpriteCollisionActive(false, false);
            g_GameMain.SetGameState(3);

            break;
    }
}

void CMan::HandleDiCollision(CWeapon* pDi)
{
    float manLeft = GetSpritePositionX() - GetSpriteWidth()/2;
    float manRight = GetSpritePositionX() + GetSpriteWidth()/2;
    float manTop = GetSpritePositionY() + GetSpriteHeight()/2;
    float manBottom = GetSpritePositionY() - GetSpriteHeight()/2;

    float diLeft = pDi->GetSpritePositionX() - pDi->GetSpriteWidth()/2;
    float diRight = pDi->GetSpritePositionX() + pDi->GetSpriteWidth()/2;
    float diTop = pDi->GetSpritePositionY() + pDi->GetSpriteHeight()/2;
    float diBottom = pDi->GetSpritePositionY() - pDi->GetSpriteHeight()/2;

    // 计算碰撞深度
    float overlapLeft = manRight - diLeft;
    float overlapRight = diRight - manLeft;
    float overlapTop = manBottom - diTop;
    float overlapBottom = diBottom - manTop;

    // 计算绝对值
    float absOverlapLeft = (overlapLeft < 0) ? -overlapLeft : overlapLeft;
    float absOverlapRight = (overlapRight < 0) ? -overlapRight : overlapRight;
    float absOverlapTop = (overlapTop < 0) ? -overlapTop : overlapTop;
    float absOverlapBottom = (overlapBottom < 0) ? -overlapBottom : overlapBottom;

    // 找出最小重叠方向
    float minOverlap = absOverlapLeft;
    if (absOverlapRight < minOverlap) minOverlap = absOverlapRight;
    if (absOverlapTop < minOverlap) minOverlap = absOverlapTop;
    if (absOverlapBottom < minOverlap) minOverlap = absOverlapBottom;

    // 根据碰撞方向处理
    if (minOverlap == absOverlapBottom) // 从上方碰撞
    {
        // 修正位置使其站在平台上
        SetSpritePositionY(diBottom - GetSpriteHeight()/2);

        // 重置Y速度
        m_fCurrentSpeedY = 0;
        SetCurrentSpeedY(0);

        // 允许跳跃
        m_bCanJump = true;
        m_bIsJumping = false;
    }
    else if (minOverlap == absOverlapTop) // 从下方碰撞
    {
        SetSpritePositionY(diTop + GetSpriteHeight()/2 + 0.1f);
        m_fCurrentSpeedY = 0.1f;
        SetCurrentSpeedY(0.1f);
    }
    else if (minOverlap == absOverlapLeft) // 从右侧碰撞
    {
        SetSpritePositionX(diLeft - GetSpriteWidth()/2);
        m_fCurrentSpeedX = 0;
        SetCurrentSpeedX(0);
    }
    else if (minOverlap == absOverlapRight) // 从左侧碰撞
    {
        SetSpritePositionX(diRight + GetSpriteWidth()/2);
        m_fCurrentSpeedX = 0;
        SetCurrentSpeedX(0);
    }
}


void CMan::SetCurrentSpeedX(float speed)
{
    m_fSpeedX = speed; // 使用基类的m_fSpeedX
    m_fCurrentSpeedX = speed; // 同时更新当前速度
}

void CMan::SetCurrentSpeedY(float speed)
{
    m_fSpeedY = speed; // 使用基类的m_fSpeedY
    m_fCurrentSpeedY = speed; // 同时更新当前速度
}
